home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / mint / mint108s.zoo / util.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-07-27  |  12.6 KB  |  640 lines

  1. /*
  2. Copyright 1990,1991,1992 Eric R. Smith.
  3. Copyright 1992 Atari Corporation.
  4. All rights reserved.
  5. */
  6.  
  7. /*
  8.  * misc. utility routines
  9.  */
  10.  
  11. #include "mint.h"
  12.  
  13. /*
  14.  * given an address, find the corresponding memory region in this program's
  15.  * memory map
  16.  */
  17.  
  18. MEMREGION *
  19. addr2mem(a)
  20.     virtaddr a;
  21. {
  22.     int i;
  23.  
  24.     for (i = 0; i < curproc->num_reg; i++) {
  25.         if (a == curproc->addr[i])
  26.             return curproc->mem[i];
  27.     }
  28.     return 0;
  29. }
  30.  
  31. /*
  32.  * given a pid, return the corresponding process
  33.  */
  34.  
  35. PROC *
  36. pid2proc(pid)
  37.     int pid;
  38. {
  39.     PROC *p;
  40.  
  41.     for (p = proclist; p; p = p->gl_next) {
  42.         if (p->pid == pid)
  43.             return p;
  44.     }
  45.     return 0;
  46. }
  47.  
  48. /*
  49.  * return a new pid
  50.  */
  51.  
  52. int
  53. newpid()
  54. {
  55.     static int _maxpid = 1;
  56.     int i;
  57. #ifndef NDEBUG
  58.     int j = 0;
  59. #endif
  60.  
  61.     do {
  62.         i = _maxpid++;
  63.         if (_maxpid >= 1000) _maxpid = 1;
  64.         assert(j++ < 1000);
  65.     } while (pid2proc(i));
  66.  
  67.     return i;
  68. }
  69.  
  70. /*
  71.  * zero out a block of memory, quickly; the block must be word-aligned,
  72.  * and should be long-aligned for speed reasons
  73.  */
  74.  
  75. void
  76. zero(place, size)
  77.     char *place;
  78.     long size;
  79. {
  80.     long cruft;
  81.  
  82.     cruft = size % 256;    /* quickzero does 256 byte blocks */
  83.     size = size / 256;
  84.     while (cruft > 0) {
  85.         *place++ = 0;
  86.         cruft--;
  87.     }
  88.     if (size > 0) {
  89.         quickzero(place, size);
  90.     }
  91. }
  92.  
  93. #ifdef JUNK_MEM
  94. void
  95. fillwjunk(place, size)
  96.     long *place;
  97.     long size;
  98. {
  99.     while (size > 0) {
  100.         *place++ = size;
  101.         size -= 4;
  102.     }
  103. }
  104. #endif
  105.  
  106. /*
  107.  * kernel memory allocation routines
  108.  */
  109.  
  110. #define KERMEM_THRESHOLD QUANTUM-8
  111. #define KMAGIC ((MEMREGION *)0x87654321L)
  112. #define NKMAGIC 0x19870425L
  113.  
  114. void * ARGS_ON_STACK 
  115. kmalloc(size)
  116.     long size;
  117. {
  118.     MEMREGION *m;
  119.     MEMREGION **p;
  120.     long *lp;
  121.  
  122.     /*
  123.      * increase size by two pointers' worth: the first contains
  124.      * a pointer to the region descriptor for this block, and the
  125.      * second contains KMAGIC.  If the block came from nalloc,
  126.      * then they both contain NKMAGIC.
  127.      */
  128.     size += sizeof(m) + sizeof(m);
  129. /*
  130.  * for small requests, we use nalloc first
  131.  */
  132. tryagain:
  133.     if (size < KERMEM_THRESHOLD) {
  134.         lp = nalloc(size);
  135.         if (lp) {
  136.         *lp++ = NKMAGIC;
  137.         *lp++ = NKMAGIC;
  138.         TRACELOW(("kmalloc(%lx) -> (nalloc) %lx",size,lp));
  139.         return lp;
  140.         }
  141.         else {
  142.         DEBUG(("kmalloc(%lx): nalloc is out of memory",size));
  143.  
  144.     /* If this is commented out, then we fall through to try_getregion */
  145.         if (0 == (m = get_region(alt, QUANTUM, PROT_S))) {
  146.             if (0 == (m = get_region(core, QUANTUM, PROT_S))) {
  147.             DEBUG(("No memory for another arena"));
  148.             goto try_getregion;
  149.             }
  150.         }
  151.         nalloc_arena_add((void *)m->loc,QUANTUM);
  152.         goto tryagain;
  153.         }
  154.     }
  155.  
  156. try_getregion:
  157.     m = get_region(alt, size, PROT_S);
  158.  
  159.     if (!m) m = get_region(core, size, PROT_S);
  160.  
  161.     if (m) {
  162.         p = (MEMREGION **)m->loc;
  163.         *p++ = KMAGIC;
  164.         *p++ = m;
  165.         TRACELOW(("kmalloc(%lx) -> (get_region) %lx",size,p));
  166.         return (void *)p;
  167.     }
  168.     else {
  169.         TRACELOW(("kmalloc(%lx) -> (fail)",size));
  170. #if 0
  171.         /* this is a serious offense; I want to hear about it */
  172.         /* maybe Allan wanted to hear about it, but ordinary users
  173.          * won't! -- ERS
  174.          */
  175.         NALLOC_DUMP();
  176.         BIG_MEM_DUMP(0,0);
  177. #endif
  178.         return 0;
  179.     }
  180. }
  181.  
  182. /* allocate from ST memory only */
  183.  
  184. void *
  185. kcore(size)
  186.     long size;
  187. {
  188.     MEMREGION *m;
  189.     MEMREGION **p;
  190.  
  191.     size += sizeof(m) + sizeof (m);
  192.     m = get_region(core, size, PROT_S);
  193.  
  194.     if (m) {
  195.         p = (MEMREGION **)m->loc;
  196.         *p++ = KMAGIC;
  197.         *p++ = m;
  198.         return (void *)p;
  199.     }
  200.     else {
  201.         return 0;
  202.     }
  203. }
  204.  
  205. void ARGS_ON_STACK 
  206. kfree(place)
  207.     void *place;
  208. {
  209.     MEMREGION **p;
  210.     MEMREGION *m;
  211.  
  212.     TRACELOW(("kfree(%lx)",place));
  213.  
  214.     if (!place) return;
  215.     p = place;
  216.     p -= 2;
  217.     if (*p == (MEMREGION *)NKMAGIC) {
  218.         nfree(p);
  219.         return;
  220.     }
  221.     else if (*p++ != KMAGIC) {
  222.         FATAL("kfree: memory not allocated by kmalloc");
  223.     }
  224.     m = *p;
  225.     if (--m->links != 0) {
  226.         FATAL("kfree: block has %d links", m->links);
  227.     }
  228.     free_region(m);
  229. }
  230.  
  231. /*
  232.  * "user" memory allocation routines; the kernel can use these to
  233.  * allocate/free memory that will be attached in some way to a process
  234.  * (and freed automatically when the process exits)
  235.  */
  236. void * ARGS_ON_STACK 
  237. umalloc(size)
  238.     long size;
  239. {
  240.     return (void *)m_xalloc(size, 3);
  241. }
  242.  
  243. void ARGS_ON_STACK 
  244. ufree(block)
  245.     void *block;
  246. {
  247.     (void)m_free((virtaddr)block);
  248. }
  249.  
  250. /*
  251.  * convert a time in milliseconds to a GEMDOS style date/time
  252.  * timeptr[0] gets the time, timeptr[1] the date.
  253.  * BUG/FEATURE: in the conversion, it is assumed that all months have
  254.  * 30 days and all years have 360 days.
  255.  */
  256.  
  257. void ARGS_ON_STACK 
  258. ms_time(ms, timeptr)
  259.     ulong ms;
  260.     short *timeptr;
  261. {
  262.     ulong secs;
  263.     short tsec, tmin, thour;
  264.     short tday, tmonth, tyear;
  265.  
  266.     secs = ms / 1000;
  267.     tsec = secs % 60;
  268.     secs /= 60;        /* secs now contains # of minutes */
  269.     tmin = secs % 60;
  270.     secs /= 60;        /* secs now contains # of hours */
  271.     thour = secs % 24;
  272.     secs /= 24;        /* secs now contains # of days */
  273.     tday = secs % 30;
  274.     secs /= 30;
  275.     tmonth = secs % 12;
  276.     tyear = secs / 12;
  277.     *timeptr++ = (thour << 11) | (tmin << 5) | (tsec >> 1);
  278.     *timeptr = (tyear << 9) | ((tmonth + 1) << 5) | (tday+1);
  279. }
  280.  
  281. /*
  282.  * unixtim(time, date): convert a Dos style (time, date) pair into
  283.  * a Unix time (seconds from midnight Jan 1., 1970)
  284.  */
  285.  
  286. static int
  287. mth_start[13] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };
  288.  
  289. long ARGS_ON_STACK 
  290. unixtim(time, date)
  291.     unsigned time, date;
  292. {
  293.     int sec, min, hour;
  294.     int mday, mon, year;
  295.     long y, s;
  296.  
  297.     sec = (time & 31) << 1;
  298.     min = (time >> 5) & 63;
  299.     hour = (time >> 11) & 31;
  300.     mday = date & 31;
  301.     mon = ((date >> 5) & 15) - 1;
  302.     year = 80 + ((date >> 9) & 255);
  303.  
  304. /* calculate tm_yday here */
  305.     y = (mday - 1) + mth_start[mon] + /* leap year correction */
  306.         ( ( (year % 4) != 0 ) ? 0 : (mon > 1) );
  307.  
  308.     s = (sec) + (min * 60L) + (hour * 3600L) +
  309.         (y * 86400L) + ((year - 70) * 31536000L) +
  310.         ((year - 69)/4) * 86400L;
  311.  
  312.     return s;
  313. }
  314.  
  315. /* convert a Unix time into a DOS time. The longword returned contains
  316.    the time word first, then the date word.
  317.    BUG: we completely ignore any time zone information.
  318. */
  319. #define SECS_PER_MIN    (60L)
  320. #define SECS_PER_HOUR   (3600L)
  321. #define SECS_PER_DAY    (86400L)
  322. #define SECS_PER_YEAR   (31536000L)
  323. #define SECS_PER_LEAPYEAR (SECS_PER_DAY + SECS_PER_YEAR)
  324.  
  325. static int
  326. days_per_mth[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
  327.  
  328. long ARGS_ON_STACK 
  329. dostim(t)
  330.     long t;
  331. {
  332.         unsigned long time, date;
  333.     int tm_hour, tm_min, tm_sec;
  334.     int tm_year, tm_mon, tm_mday;
  335.     int i;
  336.  
  337.     if (t <= 0) return 0;
  338.  
  339.     tm_year = 70;
  340.     while (t >= SECS_PER_YEAR) {
  341.         if ((tm_year & 0x3) == 0) {
  342.             if (t < SECS_PER_LEAPYEAR)
  343.                 break;
  344.             t -= SECS_PER_LEAPYEAR;
  345.         } else {
  346.             t -= SECS_PER_YEAR;
  347.         }
  348.         tm_year++;
  349.     }
  350.     tm_mday = (int)(t/SECS_PER_DAY);
  351.         days_per_mth[1] = (tm_year & 0x3) ? 28 : 29;
  352.         for (i = 0; tm_mday >= days_per_mth[i]; i++)
  353.                 tm_mday -= days_per_mth[i];
  354.         tm_mon = i+1;
  355.     tm_mday++;
  356.         t = t % SECS_PER_DAY;
  357.         tm_hour = (int)(t/SECS_PER_HOUR);
  358.         t = t % SECS_PER_HOUR;
  359.         tm_min = (int)(t/SECS_PER_MIN);
  360.         tm_sec = (int)(t % SECS_PER_MIN);
  361.  
  362.     if (tm_year < 80) {
  363.         tm_year = 80;
  364.         tm_mon = tm_mday = 1;
  365.         tm_hour = tm_min = tm_sec = 0;
  366.     }
  367.  
  368.     time = (tm_hour << 11) | (tm_min << 5) | (tm_sec >> 1);
  369.     date = ((tm_year - 80) & 0x7f) << 9;
  370.     date |= ((tm_mon) << 5) | (tm_mday);
  371.     return (time << 16) | date;
  372. }
  373.  
  374. /*
  375.  * Case insensitive string comparison. note that this only returns
  376.  * 0 (match) or nonzero (no match), and that the returned value
  377.  * is not a reliable indicator of any "order".
  378.  */
  379.  
  380. int ARGS_ON_STACK 
  381. strnicmp(str1, str2, len)
  382.     register const char *str1, *str2;
  383.     register int len;
  384. {
  385.     register char c1, c2;
  386.  
  387.     do {
  388.         c1 = *str1++; if (isupper(c1)) c1 = tolower(c1);
  389.         c2 = *str2++; if (isupper(c2)) c2 = tolower(c2);
  390.     } while (--len >= 0 && c1 && c1 == c2);
  391.  
  392.     if (len < 0 || c1 == c2)
  393.         return 0;
  394.     return c1 - c2;
  395. }
  396.  
  397. int ARGS_ON_STACK 
  398. stricmp(str1, str2)
  399.     const char *str1, *str2;
  400. {
  401.     return strnicmp(str1, str2, 0x7fff);
  402. }
  403.  
  404.  
  405. /*
  406.  * string utilities: strlwr() converts a string to lower case, strupr()
  407.  * converts it to upper case
  408.  */
  409.  
  410. char * ARGS_ON_STACK 
  411. strlwr(s)
  412.     char *s;
  413. {
  414.     char c;
  415.     char *old = s;
  416.  
  417.     while ((c = *s) != 0) {
  418.         if (isupper(c)) {
  419.             *s = _tolower(c);
  420.         }
  421.         s++;
  422.     }
  423.     return old;
  424. }
  425.  
  426. char * ARGS_ON_STACK 
  427. strupr(s)
  428.     char *s;
  429. {
  430.     char c;
  431.     char *old = s;
  432.  
  433.     while ((c = *s) != 0) {
  434.         if (islower(c)) {
  435.             *s = _toupper(c);
  436.         }
  437.         s++;
  438.     }
  439.     return old;
  440. }
  441.  
  442. #ifdef OWN_LIB
  443.  
  444. /*
  445.  * Case sensitive comparison functions.
  446.  */
  447.  
  448. int
  449. strncmp(str1, str2, len)
  450.     register const char *str1, *str2;
  451.     register int len;
  452. {
  453.     register char c1, c2;
  454.  
  455.     do {
  456.         c1 = *str1++;
  457.         c2 = *str2++;
  458.     } while (--len >= 0 && c1 && c1 == c2);
  459.  
  460.     if (len < 0) return 0;
  461.  
  462.     return c1 - c2;
  463. }
  464.  
  465. int
  466. strcmp(str1, str2)
  467.     const char *str1, *str2;
  468. {
  469.     register char c1, c2;
  470.  
  471.     do {
  472.         c1 = *str1++;
  473.         c2 = *str2++;
  474.     } while (c1 && c1 == c2);
  475.  
  476.     return c1 - c2;
  477. }
  478.  
  479.  
  480. /*
  481.  * some standard string functions
  482.  */
  483.  
  484. char *
  485. strcat(dst, src)
  486.     char *dst;
  487.     const char *src;
  488. {
  489.     register char *_dscan;
  490.  
  491.     for (_dscan = dst; *_dscan; _dscan++) ;
  492.     while ((*_dscan++ = *src++) != 0) ;
  493.     return dst;
  494. }
  495.  
  496. char *
  497. strcpy(dst, src)
  498.     char *dst;
  499.     const char *src;
  500. {
  501.     register char *_dscan = dst;
  502.     while ((*_dscan++ = *src++) != 0) ;
  503.     return dst;
  504. }
  505.  
  506. char *
  507. strncpy(dst, src, len)
  508.     char *dst;
  509.     const char *src;
  510.     int len;
  511. {
  512.     register char *_dscan = dst;
  513.     while (--len >= 0 && (*_dscan++ = *src++) != 0)
  514.         continue;
  515.     while (--len >= 0)
  516.         *_dscan++ = 0;
  517.     return dst;
  518. }
  519.  
  520. int
  521. strlen(scan)
  522.     const char *scan;
  523. {
  524.     register const char *_start = scan+1;
  525.     while (*scan++) ;
  526.     return (int)((long)scan - (long)_start);
  527. }
  528.  
  529. /*
  530.  * strrchr: find the last occurence of a character in a string
  531.  */
  532. char *
  533. strrchr(str, which)
  534.     const char *str;
  535.     register int which;
  536. {
  537.     register unsigned char c, *s;
  538.     register char *place;
  539.  
  540.     s = (unsigned char *)str;
  541.     place = 0;
  542.     do {
  543.         c = *s++;
  544.         if (c == which)
  545.             place = (char *)s-1;
  546.     } while (c);
  547.     return place;
  548. }
  549.  
  550. unsigned char _ctype[256] =
  551. {
  552.     _CTc, _CTc, _CTc, _CTc,                /* 0x00..0x03 */
  553.     _CTc, _CTc, _CTc, _CTc,                /* 0x04..0x07 */
  554.     _CTc, _CTc|_CTs, _CTc|_CTs, _CTc|_CTs,        /* 0x08..0x0B */
  555.     _CTc|_CTs, _CTc|_CTs, _CTc, _CTc,        /* 0x0C..0x0F */
  556.  
  557.     _CTc, _CTc, _CTc, _CTc,                /* 0x10..0x13 */
  558.     _CTc, _CTc, _CTc, _CTc,                /* 0x14..0x17 */
  559.     _CTc, _CTc, _CTc, _CTc,                /* 0x18..0x1B */
  560.     _CTc, _CTc, _CTc, _CTc,                /* 0x1C..0x1F */
  561.  
  562.     _CTs, _CTp, _CTp, _CTp,                /* 0x20..0x23 */
  563.     _CTp, _CTp, _CTp, _CTp,                /* 0x24..0x27 */
  564.     _CTp, _CTp, _CTp, _CTp,                /* 0x28..0x2B */
  565.     _CTp, _CTp, _CTp, _CTp,                /* 0x2C..0x2F */
  566.  
  567.     _CTd|_CTx, _CTd|_CTx, _CTd|_CTx, _CTd|_CTx,    /* 0x30..0x33 */
  568.     _CTd|_CTx, _CTd|_CTx, _CTd|_CTx, _CTd|_CTx,    /* 0x34..0x37 */
  569.     _CTd|_CTx, _CTd|_CTx, _CTp, _CTp,        /* 0x38..0x3B */
  570.     _CTp, _CTp, _CTp, _CTp,                /* 0x3C..0x3F */
  571.  
  572.     _CTp, _CTu|_CTx, _CTu|_CTx, _CTu|_CTx,        /* 0x40..0x43 */
  573.     _CTu|_CTx, _CTu|_CTx, _CTu|_CTx, _CTu,        /* 0x44..0x47 */
  574.     _CTu, _CTu, _CTu, _CTu,                /* 0x48..0x4B */
  575.     _CTu, _CTu, _CTu, _CTu,                /* 0x4C..0x4F */
  576.  
  577.     _CTu, _CTu, _CTu, _CTu,                /* 0x50..0x53 */
  578.     _CTu, _CTu, _CTu, _CTu,                /* 0x54..0x57 */
  579.     _CTu, _CTu, _CTu, _CTp,                /* 0x58..0x5B */
  580.     _CTp, _CTp, _CTp, _CTp,                /* 0x5C..0x5F */
  581.  
  582.     _CTp, _CTl|_CTx, _CTl|_CTx, _CTl|_CTx,        /* 0x60..0x63 */
  583.     _CTl|_CTx, _CTl|_CTx, _CTl|_CTx, _CTl,        /* 0x64..0x67 */
  584.     _CTl, _CTl, _CTl, _CTl,                /* 0x68..0x6B */
  585.     _CTl, _CTl, _CTl, _CTl,                /* 0x6C..0x6F */
  586.  
  587.     _CTl, _CTl, _CTl, _CTl,                /* 0x70..0x73 */
  588.     _CTl, _CTl, _CTl, _CTl,                /* 0x74..0x77 */
  589.     _CTl, _CTl, _CTl, _CTp,                /* 0x78..0x7B */
  590.     _CTp, _CTp, _CTp, _CTc,                /* 0x7C..0x7F */
  591.  
  592.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80..0x8F */
  593.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90..0x9F */
  594.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xA0..0xAF */
  595.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xB0..0xBF */
  596.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xC0..0xCF */
  597.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xD0..0xDF */
  598.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xE0..0xEF */
  599.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0  /* 0xF0..0xFF */
  600. };
  601.  
  602. int toupper(c)
  603.     int c;
  604. {
  605.     return(islower(c) ? (c ^ 0x20) : (c));
  606. }
  607.  
  608. int tolower(c)
  609.     int c;
  610. {
  611.     return(isupper(c) ? (c ^ 0x20) : (c));
  612. }
  613.  
  614. /*
  615.  * converts a decimal string to an integer
  616.  */
  617.  
  618. long
  619. atol(s)
  620.     const char *s;
  621. {
  622.     long d = 0;
  623.     int negflag = 0;
  624.     int c;
  625.  
  626.     while (*s && isspace(*s)) s++;
  627.     while (*s == '-' || *s == '+') {
  628.         if (*s == '-')
  629.             negflag ^= 1;
  630.         s++;
  631.     }
  632.     while ((c = *s++) != 0 && isdigit(c)) {
  633.         d = 10 * d + (c - '0');
  634.     }
  635.     if (negflag) d = -d;
  636.     return d;
  637. }
  638.  
  639. #endif /* OWN_LIB */
  640.